package com.ruoyi.iot.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.ruoyi.iot.domain.*;
import com.ruoyi.iot.domain.vo.*;
import com.ruoyi.iot.domain.vo.drop.CmdVoInfo;
import com.ruoyi.iot.domain.vo.exchange.IotWrapperDTO;
import com.ruoyi.iot.domain.vo.field.DecodeObj;
import com.ruoyi.iot.domain.vo.field.EncodeObj;
import com.ruoyi.iot.domain.vo.plus.IotCmdPlus;
import com.ruoyi.iot.service.impl.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.iot.service.IIotCmdService;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.utils.poi.ExcelUtil;

/**
 * 指令Controller
 *
 * @author ruoyi
 * @date 2022-12-27
 */
@RestController
@RequestMapping("/cmd")
public class IotCmdController extends BaseController
{

    /**
     * 指令服务
     */
    @Autowired
    private IIotCmdService iotCmdService;


    /**
     * 产品服务
     */
    @Autowired
    private IotProductServiceImpl iotProductService;

    /**
     * 指令解码
     */
    @Autowired
    private IotCmdDecodeServiceImpl iotCmdDecodeService;

    /**
     * 指令编码
     */
    @Autowired
    private IotCmdEncoderServiceImpl iotCmdEncoderService;

    /**
     * 数据包字段服务
     */
    @Autowired
    private IotProductFieldServiceImpl iotProductFieldService;

    /**
     * 指令解释服务
     */
    @Autowired
    private IotCmdExplainServiceImpl iotCmdExplainService;


    /**
     * 查询指令列表
     */
    @RequiresPermissions("iot:cmd:list")
    @GetMapping("/list")
    @Deprecated
    public CmdVoInfo list(IotCmd iotCmd)
    {
        //报文map

        startPage();

        List<IotCmd> list = iotCmdService.selectIotCmdList(iotCmd);

        List<IotCmdPlus> plusList = new ArrayList<>();
        for(IotCmd item : list) {
            IotCmdPlus cmdPlus = new IotCmdPlus();
            BeanUtils.copyProperties(item,cmdPlus);
            cmdPlus.setProductName(iotProductService.selectIotProductById(item.getProductId()).getName());
            plusList.add(cmdPlus);
        }


        CmdVoInfo rspData = new CmdVoInfo();
        rspData.setCode(200);
        rspData.setRows(plusList);
        List<IotProduct> products = iotProductService.selectIotProductList(new IotProduct());
        List<CmdProductFieldVO> productFields = getProductFieldVo();
        rspData.setProductList(products);
        rspData.setProductFields(productFields);
        rspData.setMsg("查询成功");
        rspData.setTotal((new PageInfo(list)).getTotal());

        return rspData;
    }

    /**
     * 查询指令列表
     */
    @PostMapping("/query/list")
    public IotWrapperDTO<List<IotCmd>> queryList(@RequestBody IotCmd iotCmd) {
        IotWrapperDTO<List<IotCmd>> iotListDTO = new IotWrapperDTO<>();
        List<IotCmd> list = iotCmdService.selectIotCmdList(iotCmd);
        iotListDTO.setData(list);
        return iotListDTO;
    }






    /**
     * 导出指令列表
     */
    @RequiresPermissions("iot:cmd:export")
    @Log(title = "指令", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, IotCmd iotCmd)
    {
        List<IotCmd> list = iotCmdService.selectIotCmdList(iotCmd);
        ExcelUtil<IotCmd> util = new ExcelUtil<IotCmd>(IotCmd.class);
        util.exportExcel(response, list, "指令数据");
    }

    /**
     * 获取指令详细信息
     */
    @RequiresPermissions("iot:cmd:query")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return AjaxResult.success(iotCmdService.selectIotCmdById(id));
    }



    /**
     * 获取解释的文本信息
     * @param cmdId 指令id
     * @return
     */
    @GetMapping(value = "explain/{id}")
    public AjaxResult getIotCmdExplain(@PathVariable("id") Long cmdId){
        IotCmdExplain iotCmdExplain = new IotCmdExplain();
        iotCmdExplain.setCmdId(cmdId);
        List<IotCmdExplain> cmdExplains =  iotCmdExplainService.selectIotCmdExplainList(iotCmdExplain);
        DevCmdVo devCmdVo = null;


        if(cmdExplains.size() == 0 ) {
            devCmdVo =  new DevCmdVo();
            JSONObject json = new JSONObject();
            json.put("tip","please config cmd");
            devCmdVo.setData(json);
        } else {

           String jsonStr =  cmdExplains.get(0).getJson();
            devCmdVo = JSON.parseObject(jsonStr,DevCmdVo.class);
        }

        return AjaxResult.success(devCmdVo);
    }


    /**
     * 新增指令
     */
    @RequiresPermissions("iot:cmd:add")
    @Log(title = "指令", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody IotCmd iotCmd)
    {
        return toAjax(iotCmdService.insertIotCmd(iotCmd));
    }

    /**
     * 修改指令
     */
    @RequiresPermissions("iot:cmd:edit")
    @Log(title = "指令", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody IotCmd iotCmd)
    {
        return toAjax(iotCmdService.updateIotCmd(iotCmd));
    }

    /**
     * 删除指令
     */
    @RequiresPermissions("iot:cmd:remove")
    @Log(title = "指令", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(iotCmdService.deleteIotCmdByIds(ids));
    }


    /**
     * 组装编码指令的字段
     * @param cmdEncodeJsonVo 指令编码数据
     * @return
     */
    @PostMapping("/generator/encode/json")
    public AjaxResult composeCmdEncode(@RequestBody CmdJsonEncodeVo cmdEncodeJsonVo){
       // System.out.println(JSON.toJSON(cmdEncodeJsonVo));
        Long cmdId =  cmdEncodeJsonVo.getCmdId();

        //删除掉之前生成的指令逻辑字段
        IotCmdEncoder iotCmdEncoder = new IotCmdEncoder();
        iotCmdEncoder.setCmdId(cmdId);
        List<IotCmdEncoder> iotCmdEncoders = iotCmdEncoderService.selectIotCmdEncoderList(iotCmdEncoder);
        for(IotCmdEncoder item: iotCmdEncoders) {
            iotCmdDecodeService.deleteIotCmdDecodeById(item.getId());
        }

        //生成
        List<EncodeObj> encodeObjs =   cmdEncodeJsonVo.getEncodeObjs();
        for (EncodeObj encodeObj : encodeObjs) {
            IotCmdEncoder iotCmdEncoderDo = new IotCmdEncoder();
            iotCmdEncoderDo.setCmdId(cmdId);
            iotCmdEncoderDo.setSequence(encodeObj.getIndex().longValue());
            iotCmdEncoderDo.setFieldId(encodeObj.getFieldId());
            iotCmdEncoderDo.setRemark(encodeObj.getFieldName());
            iotCmdEncoderService.insertIotCmdEncoder(iotCmdEncoderDo);
        }
        DevCmdVo devCmdVo = generateCmdEncode(cmdEncodeJsonVo);
        //删除cmd解释表
        deleteCmdExplain(cmdId);
        //插入到解释框中
        insertCmdExplain(cmdId,devCmdVo);
        return AjaxResult.success(devCmdVo);
    }

    /**
     * 组装解码指令的字段
     * @param cmdJsonDecodeVo 指令解码vo
     * @return
     */
    @PostMapping("/generator/decode/json")
    public AjaxResult composeCmdDecode(@RequestBody CmdJsonDecodeVo cmdJsonDecodeVo){
      //  System.out.println(JSON.toJSON(cmdJsonDecodeVo));
        //指令cmdId
        Long cmdId =  cmdJsonDecodeVo.getCmdId();
        //删除掉之前生成的指令逻辑字段
        IotCmdDecode cmdDecode = new IotCmdDecode();
        cmdDecode.setCmdId(cmdId);
        List<IotCmdDecode> iotCmdDecodes = iotCmdDecodeService.selectIotCmdDecodeList(cmdDecode);
        for(IotCmdDecode item: iotCmdDecodes) {
            iotCmdDecodeService.deleteIotCmdDecodeById(item.getId());
        }
        //开始生成
        List<DecodeObj> decodeObjs =  cmdJsonDecodeVo.getDecodeObjs();
        for (DecodeObj decodeObj : decodeObjs) {
            IotCmdDecode iotCmdDecode = new IotCmdDecode();
            iotCmdDecode.setCmdId(cmdId);
            iotCmdDecode.setSequence(decodeObj.getIndex().longValue());
            iotCmdDecode.setTrimType(decodeObj.getTrimType().longValue());
            iotCmdDecode.setTrimParam(decodeObj.getTrimParam().longValue());
            iotCmdDecode.setFieldId(decodeObj.getFieldId().longValue());
            iotCmdDecode.setRemark(decodeObj.getFieldName());
            iotCmdDecodeService.insertIotCmdDecode(iotCmdDecode);
        }
        DevCmdVo devCmdVo = generateCmdDecode(cmdJsonDecodeVo);
        //删除cmd解释表
        deleteCmdExplain(cmdId);
        //插入到解释框中
        insertCmdExplain(cmdId,devCmdVo);

        return AjaxResult.success(devCmdVo);
    }


    /**
     * 获取包id 和 对应的 包字段列表
     * @return
     */
    private List<CmdProductFieldVO> getProductFieldVo() {
        List<CmdProductFieldVO> cmdProductFieldVOS = new ArrayList<>();

        List<IotProduct> products = iotProductService.selectIotProductList(new IotProduct());
        IotProductField iotProductField = new IotProductField();
        for(IotProduct item : products) {
            Long productId = item.getId();
            iotProductField.setProductId(productId);
            List<IotProductField> productFields = iotProductFieldService.selectIotProductFieldList(iotProductField);
            List<IotProductFieldVo> iotProductFieldVos = new ArrayList<>();
            for(IotProductField childItem: productFields) {
                IotProductFieldVo iotProductFieldVo = new IotProductFieldVo();
                BeanUtils.copyProperties(childItem, iotProductFieldVo);
                iotProductFieldVos.add(iotProductFieldVo);
            }
            CmdProductFieldVO cmdProductFieldVO = new CmdProductFieldVO();
            cmdProductFieldVO.setProductId(productId + "");
            cmdProductFieldVO.setProductFieldVoList(iotProductFieldVos);
            cmdProductFieldVOS.add(cmdProductFieldVO);
        }
        return cmdProductFieldVOS;
    }


    /**
     * 删除cmd解释字段
     * @param cmdId
     */
    private void deleteCmdExplain(Long cmdId) {
        IotCmdExplain iotCmdExplain = new IotCmdExplain();
        iotCmdExplain.setCmdId(cmdId);
        List<IotCmdExplain> iotCmdExplains = iotCmdExplainService.selectIotCmdExplainList(iotCmdExplain);
        for(IotCmdExplain item: iotCmdExplains) {
            iotCmdExplainService.deleteIotCmdExplainById(item.getId());
        }
    }


    /**
     * 插入cmd的解释字段
     * @param cmdId
     */
    private void insertCmdExplain(Long cmdId,DevCmdVo devCmdVo) {
        IotCmd iotCmd = iotCmdService.selectIotCmdById(cmdId);
        String productName = iotProductService.selectIotProductById(iotCmd.getProductId()).getName();
        Long sponsor = iotCmd.getSponsor();
        IotCmdExplain iotCmdExplain = new IotCmdExplain();
        iotCmdExplain.setCmdId(cmdId);
        iotCmdExplain.setSponsor(sponsor);
        iotCmdExplain.setJson(JSON.toJSONString(devCmdVo));
        iotCmdExplain.setRemark(productName + " ==> " + iotCmd.getRemark());
        iotCmdExplain.setCreator(1L);
        iotCmdExplain.setCreateDate(new Date());
        iotCmdExplainService.insertIotCmdExplain(iotCmdExplain);
    }


    /**
     * 生成指令解码json
     * @param cmdJsonDecodeVo 解码的数据
     * @return
     */
    private DevCmdVo generateCmdDecode(CmdJsonDecodeVo cmdJsonDecodeVo) {
        DevCmdVo devCmdVo = new DevCmdVo();
        devCmdVo.setDevId("0000000001");
        devCmdVo.setCmdId(cmdJsonDecodeVo.getCmdId());
        JSONObject json = new JSONObject();
        List<DecodeObj> decodeObjs = cmdJsonDecodeVo.getDecodeObjs();
        for(DecodeObj item: decodeObjs) {
           Long fieldId =  item.getFieldId();
           IotProductField iotProductField =  iotProductFieldService.selectIotProductFieldById(fieldId);
           String fieldKey = iotProductField.getField();
           Object fieldValue  = iotProductField.getDefVal();
           json.put(fieldKey,fieldValue);
        }
        devCmdVo.setData(json);
        return devCmdVo;
    }

    /**
     * 生成指令编码json
     * @param cmdEncodeJsonVo 编码的数据
     * @return
     */
    private DevCmdVo generateCmdEncode(CmdJsonEncodeVo cmdEncodeJsonVo) {
        DevCmdVo devCmdVo = new DevCmdVo();
        devCmdVo.setDevId("0000000001");
        devCmdVo.setCmdId(cmdEncodeJsonVo.getCmdId());
        JSONObject json = new JSONObject();
        List<EncodeObj> encodeObjs = cmdEncodeJsonVo.getEncodeObjs();
        for(EncodeObj item: encodeObjs) {
            Long fieldId =  item.getFieldId();
            IotProductField iotProductField =  iotProductFieldService.selectIotProductFieldById(fieldId);
            String fieldKey = iotProductField.getField();
            Object fieldValue  = iotProductField.getDefVal();
            json.put(fieldKey,fieldValue);
        }
        devCmdVo.setData(json);
        return devCmdVo;
    }


}
